#pragma once

class Vector2
{
public:
	static const Vector2 Zero;
	static const Vector2 One;
	static const Vector2 UnitX;
	static const Vector2 UnitY;
	float X, Y;

	Vector2() {}
	Vector2(float s) : X(s), Y(s) {}
	Vector2(float x, float y) : X(x), Y(y) {}
	Vector2(const Vector2& v) : X(v.X), Y(v.Y) {}
	
	Vector2 operator+( const Vector2& v ) const { return Vector2( X + v.X, Y + v.Y); }
	Vector2 operator-( const Vector2& v ) const { return Vector2( X - v.X, Y - v.Y); }
	Vector2 operator*( float Scale ) const { return Vector2( X * Scale, Y * Scale); }
	Vector2 operator/( float Scale ) const { const float RScale = 1.f/Scale; return Vector2( X * RScale, Y * RScale); }
	Vector2 operator*( const Vector2& v ) const { return Vector2(X * v.X, Y * v.Y); }
	Vector2 operator/( const Vector2& v ) const { return Vector2(X / v.X, Y / v.Y); }

	// Binary comparison operators.
	bool operator==( const Vector2& v ) const { return X==v.X && Y==v.Y; }
	bool operator!=( const Vector2& v ) const { return X!=v.X || Y!=v.Y; }

	// Unary operators.
	Vector2 operator-() const { return Vector2( -X, -Y); }

	// Assignment operators.
	Vector2 operator+=( const Vector2& v ) { X += v.X; Y += v.Y; return *this; }
	Vector2 operator-=( const Vector2& v ) { X -= v.X; Y -= v.Y; return *this; }
	Vector2 operator*=( float Scale ) { X *= Scale; Y *= Scale; return *this; }
	Vector2 operator/=( float v ) { const float RV = 1.f/v; X *= RV; Y *= RV; return *this; }
	Vector2 operator*=( const Vector2& v ) { X *= v.X; Y *= v.Y; return *this; }
	Vector2 operator/=( const Vector2& v ) { X /= v.X; Y /= v.Y; return *this; }

	inline bool Normalize(float Tolerance = SMALL_NUMBER)
	{
		const float SquareSum = X*X + Y*Y;
		if (SquareSum > Tolerance)
		{
			const float Scale = appInvSqrt(SquareSum);
			X *= Scale; Y *= Scale;
			return true;
		}
		return false;
	}

	inline Vector2 UnsafeNormal() const
	{
		const float Scale = appInvSqrt(X*X + Y*Y);
		return Vector2(X * Scale, Y * Scale);
	}

	inline void MakeFloor(const Vector2& v)
	{
		if (v.X < X) X = v.X;
		if (v.Y < Y) X = v.Y;
	}
	
	inline void MakeCeil(const Vector2& v)
	{
		if (v.X > X) X = v.X;
		if (v.Y > Y) X = v.Y;
	}
};
